---
title: "Receiving Message"
categories:
- java
- spring-amqp
tags:
---

<div id="content">
<div id="table-of-contents">
<h2>Table of Contents</h2>
<div id="text-table-of-contents">
<ul>
<li><a href="#org9b512cd">Polling Consumer</a></li>
<li><a href="#org2b41ace">Asynchronous Consumer (推荐的方式）</a>
<ul>
<li><a href="#orge6981ff">Callback Interfaces</a></li>
<li><a href="#org78521a3">MessageListenerAdapter</a></li>
<li><a href="#orgd002c81">Container</a></li>
</ul>
</li>
<li><a href="#org5e17f9c">注解方式Listener</a></li>
</ul>
</div>
</div>
<dl class="org-dl">
<dt>polling consumer</dt><dd>The simpler option is to poll for one Message at a time with a polling method call</dd>
<dt>Asynchronous Consumer</dt><dd>register a listener that receives Messages on-demand, asynchronously</dd>
</dl>
<div class="outline-2" id="outline-container-org9b512cd">
<h2 id="org9b512cd">Polling Consumer</h2>
<div class="outline-text-2" id="text-org9b512cd">
<p>
调用 {% raw %} AmqpTemplate {% endraw %} 中的方法拉取消息。
默认情况下，如果没有消息，则方法立即返回（非阻塞）。
从1.5开始，支持receiveTimeout ( millisecond )，方法在这段时间内阻塞直到有消息到达。指定小于0的值表示永久阻塞直到消息到达。
</p>
</div>
</div>
<div class="outline-2" id="outline-container-org2b41ace">
<h2 id="org2b41ace">Asynchronous Consumer (推荐的方式）</h2>
<div class="outline-text-2" id="text-org2b41ace">
</div>
<div class="outline-3" id="outline-container-orge6981ff">
<h3 id="orge6981ff">Callback Interfaces</h3>
<div class="outline-text-3" id="text-orge6981ff">
<ul class="org-ul">
<li>MessageListener</li>
</ul>
<div class="org-src-container">
<pre class="src src-java"><span style="font-weight: bold;">public</span> <span style="font-weight: bold;">interface</span> <span style="font-weight: bold; text-decoration: underline;">MessageListener</span> {
    <span style="font-weight: bold; text-decoration: underline;">void</span> <span style="font-weight: bold;">onMessage</span>(<span style="font-weight: bold; text-decoration: underline;">Message</span> <span style="font-weight: bold; font-style: italic;">message</span>);
}
</pre>
</div>
<dl class="org-dl">
<dt>ChannelAwareMessageListener</dt><dd>onMessage回调方法提供了另外一个Channel对象，当回调逻辑中需要这个对象时有用</dd>
</dl>
<div class="org-src-container">
<pre class="src src-java"><span style="font-weight: bold;">public</span> <span style="font-weight: bold;">interface</span> <span style="font-weight: bold; text-decoration: underline;">ChannelAwareMessageListener</span> {
    <span style="font-weight: bold; text-decoration: underline;">void</span> <span style="font-weight: bold;">onMessage</span>(<span style="font-weight: bold; text-decoration: underline;">Message</span> <span style="font-weight: bold; font-style: italic;">message</span>, <span style="font-weight: bold; text-decoration: underline;">Channel</span> <span style="font-weight: bold; font-style: italic;">channel</span>) <span style="font-weight: bold;">throws</span> <span style="font-weight: bold; text-decoration: underline;">Exception</span>;
}
</pre>
</div>
</div>
</div>
<div class="outline-3" id="outline-container-org78521a3">
<h3 id="org78521a3">MessageListenerAdapter</h3>
<div class="outline-text-3" id="text-org78521a3">
<p>
框架提供的适配器实现。也常被称作 <b>Message Driven POJO Support</b> ，当希望在应用逻辑和消息API之间有严格的区分时使用。
</p>
<div class="org-src-container">
<pre class="src src-java"><span style="font-weight: bold; text-decoration: underline;">MessageListenerAdapter</span> <span style="font-weight: bold; font-style: italic;">listener</span> = <span style="font-weight: bold;">new</span> <span style="font-weight: bold; text-decoration: underline;">MessageListenerAdapter</span>(somePojo);
listener.setDefaultListenerMethod(<span style="font-style: italic;">"myMethod"</span>);
</pre>
</div>
<p>
也能继承这个Adapter并实现 getListenerMethodName(originalMessage, extractedMessage) 方法，以基于消息动态选择不同的方法。
</p>
</div>
</div>
<div class="outline-3" id="outline-container-orgd002c81">
<h3 id="orgd002c81">Container</h3>
<div class="outline-text-3" id="text-orgd002c81">
<p>
Listener(callback)是被动调用的，而container则负责“主动”的那部分。
当配置container的时候，就建立了AMQP Queue和MessageListener之间的关联。
</p>
<p>
2.0以前只有一个container实现——SimpleMessageListenerContainer，现在有了第二个实现——DirectMessageListenerContainer。
</p>
<p>
Using SimpleMessageListenerContainer
</p>
<div class="org-src-container">
<pre class="src src-java"><span style="font-weight: bold; text-decoration: underline;">SimpleMessageListenerContainer</span> <span style="font-weight: bold; font-style: italic;">container</span> = <span style="font-weight: bold;">new</span> <span style="font-weight: bold; text-decoration: underline;">SimpleMessageListenerContainer</span>();
container.setConnectionFactory(rabbitConnectionFactory);
container.setQueueNames(<span style="font-style: italic;">"some.queue"</span>);
container.setMessageListener(<span style="font-weight: bold;">new</span> <span style="font-weight: bold; text-decoration: underline;">MessageListenerAdapter</span>(somePojo));
</pre>
</div>
<p>
而作为一个“主动”组件，一般是将其创建为一个bean，使其能够在后台运行：
</p>
<div class="org-src-container">
<pre class="src src-java"><span style="font-weight: bold; text-decoration: underline;">@Configuration</span>
<span style="font-weight: bold;">public</span> <span style="font-weight: bold;">class</span> <span style="font-weight: bold; text-decoration: underline;">ExampleAmqpConfiguration</span> {

    <span style="font-weight: bold; text-decoration: underline;">@Bean</span>
    <span style="font-weight: bold;">public</span> <span style="font-weight: bold; text-decoration: underline;">SimpleMessageListenerContainer</span> <span style="font-weight: bold;">messageListenerContainer</span>() {
        <span style="font-weight: bold; text-decoration: underline;">SimpleMessageListenerContainer</span> <span style="font-weight: bold; font-style: italic;">container</span> = <span style="font-weight: bold;">new</span> <span style="font-weight: bold; text-decoration: underline;">SimpleMessageListenerContainer</span>();
        container.setConnectionFactory(rabbitConnectionFactory());
        container.setQueueName(<span style="font-style: italic;">"some.queue"</span>);
        container.setMessageListener(exampleListener());
        <span style="font-weight: bold;">return</span> container;
    }

    <span style="font-weight: bold; text-decoration: underline;">@Bean</span>
    <span style="font-weight: bold;">public</span> <span style="font-weight: bold; text-decoration: underline;">ConnectionFactory</span> <span style="font-weight: bold;">rabbitConnectionFactory</span>() {
        <span style="font-weight: bold; text-decoration: underline;">CachingConnectionFactory</span> <span style="font-weight: bold; font-style: italic;">connectionFactory</span> =
            <span style="font-weight: bold;">new</span> <span style="font-weight: bold; text-decoration: underline;">CachingConnectionFactory</span>(<span style="font-style: italic;">"localhost"</span>);
        connectionFactory.setUsername(<span style="font-style: italic;">"guest"</span>);
        connectionFactory.setPassword(<span style="font-style: italic;">"guest"</span>);
        <span style="font-weight: bold;">return</span> connectionFactory;
    }

    <span style="font-weight: bold; text-decoration: underline;">@Bean</span>
    <span style="font-weight: bold;">public</span> <span style="font-weight: bold; text-decoration: underline;">MessageListener</span> <span style="font-weight: bold;">exampleListener</span>() {
        <span style="font-weight: bold;">return</span> <span style="font-weight: bold;">new</span> <span style="font-weight: bold; text-decoration: underline;">MessageListener</span>() {
            <span style="font-weight: bold;">public</span> <span style="font-weight: bold; text-decoration: underline;">void</span> <span style="font-weight: bold;">onMessage</span>(<span style="font-weight: bold; text-decoration: underline;">Message</span> <span style="font-weight: bold; font-style: italic;">message</span>) {
                System.out.println(<span style="font-style: italic;">"received: "</span> + message);
            }
        };
    }
}
</pre>
</div>
</div>
</div>
</div>
<div class="outline-2" id="outline-container-org5e17f9c">
<h2 id="org5e17f9c">注解方式Listener</h2>
<div class="outline-text-2" id="text-org5e17f9c">
<div class="org-src-container">
<pre class="src src-java"><span style="font-weight: bold; text-decoration: underline;">@Component</span>
<span style="font-weight: bold;">public</span> <span style="font-weight: bold;">class</span> <span style="font-weight: bold; text-decoration: underline;">MyService</span> {

    <span style="font-weight: bold; text-decoration: underline;">@RabbitListener</span>(queues = <span style="font-style: italic;">"myQueue"</span>)
    <span style="font-weight: bold;">public</span> <span style="font-weight: bold; text-decoration: underline;">void</span> <span style="font-weight: bold;">processOrder</span>(<span style="font-weight: bold; text-decoration: underline;">String</span> <span style="font-weight: bold; font-style: italic;">data</span>) {
        ...
    }

}
</pre>
</div>
<p>
对每一个扫描到的注解了的方法，使用RabbitListenerContainerFactory创建一个message container
</p>
</div>
</div>
</div>
<div class="status" id="postamble">
<p class="author">Author: amo</p>
<p class="validation"><a href="http://validator.w3.org/check?uri=referer">Validate</a></p>
</div>
